{ "cells": [ { "cell_type": "markdown", "id": "80924601", "metadata": {}, "source": [ "# Programming Techniques — Laboratory — INSTRUCTOR VERSION\n", "## Input, Type Conversion and Strings\n", "\n", "This is the **worked version** of the student laboratory.\n", "\n", "It follows the same progression:\n", "1. Guided exercise\n", "2. Semi-independent laboratory exercises\n", "3. Independent review / homework\n", "\n", "Solutions intentionally use only concepts already introduced in the course." ] }, { "cell_type": "markdown", "id": "4d29ecaf", "metadata": {}, "source": [ "---\n", "# Part B — Laboratory\n", "\n", "Work on the following exercises semi-independently.\n", "\n", "You are encouraged to test small expressions, compare results, ask questions, and discuss alternative solutions." ] }, { "cell_type": "markdown", "id": "96cbe770", "metadata": {}, "source": [ "## 2. Product code inspector\n", "\n", "### Theory recall\n", "\n", "A string is an **ordered sequence of characters**.\n", "\n", "```python\n", "code = \"LIS-2026-A7\"\n", "\n", "len(code) # number of characters\n", "code[0] # first character\n", "code[-1] # last character\n", "```\n", "\n", "Python indexes start from `0`. Negative indexes count from the end.\n", "\n", "### Task\n", "\n", "A company uses product identifiers with this format:\n", "\n", "```text\n", "LIS-2026-A7\n", "```\n", "\n", "where:\n", "- `LIS` is the office code;\n", "- `2026` is the year;\n", "- `A7` is the product family.\n", "\n", "Ask the user to enter a code in this format and print:\n", "1. the complete code;\n", "2. its total length;\n", "3. the first character;\n", "4. the last character;\n", "5. the office code;\n", "6. the year;\n", "7. the product family.\n", "\n", "Use **indexes/slicing** and an **f-string**.\n", "\n", "Hint:\n", "\n", "```python\n", "text[start:stop]\n", "```\n", "\n", "The `stop` position is **excluded**." ] }, { "cell_type": "code", "execution_count": null, "id": "2c52d59b", "metadata": { "tags": [ "solution" ] }, "outputs": [], "source": [ "product_code = input(\"Product code (e.g. LIS-2026-A7): \")\n", "\n", "office = product_code[0:3]\n", "year = product_code[4:8]\n", "family = product_code[9:]\n", "\n", "print(f\"Complete code: {product_code}\")\n", "print(f\"Length: {len(product_code)} characters\")\n", "print(f\"First character: {product_code[0]}\")\n", "print(f\"Last character: {product_code[-1]}\")\n", "print(f\"Office: {office}\")\n", "print(f\"Year: {year}\")\n", "print(f\"Product family: {family}\")" ] }, { "cell_type": "markdown", "id": "4a654b58", "metadata": {}, "source": [ "## 3. Reading a code forwards and backwards\n", "\n", "### Theory recall\n", "\n", "Slicing can include a third parameter, the **step**:\n", "\n", "```python\n", "text[start:stop:step]\n", "```\n", "\n", "Examples:\n", "\n", "```python\n", "text[::2] # every second character\n", "text[::-1] # the whole string in reverse order\n", "```\n", "\n", "A negative step means that Python moves **from right to left**.\n", "\n", "### Task\n", "\n", "Ask for a tracking code and display:\n", "- the original code;\n", "- the code reversed;\n", "- characters in even index positions: `0, 2, 4, ...`;\n", "- characters in odd index positions: `1, 3, 5, ...`;\n", "- characters from index `6` down to index `2` (index `2` excluded).\n", "\n", "Use only slicing." ] }, { "cell_type": "code", "execution_count": null, "id": "ebee172b", "metadata": { "tags": [ "solution" ] }, "outputs": [], "source": [ "tracking = input(\"Tracking code: \")\n", "\n", "print(f\"Original: {tracking}\")\n", "print(f\"Reversed: {tracking[::-1]}\")\n", "print(f\"Even positions: {tracking[::2]}\")\n", "print(f\"Odd positions: {tracking[1::2]}\")\n", "print(f\"Index 6 to 3: {tracking[6:2:-1]}\")" ] }, { "cell_type": "markdown", "id": "bf9d3469", "metadata": {}, "source": [ "## 4. Mini sales histogram\n", "\n", "### Theory recall\n", "\n", "Escape sequences represent special characters inside strings:\n", "\n", "```python\n", "\"\\n\" # new line\n", "\"\\t\" # horizontal tab\n", "\"\\\\\" # backslash\n", "```\n", "\n", "Strings can also be repeated:\n", "\n", "```python\n", "\"*\" * 5 # \"*****\"\n", "```\n", "\n", "### Task\n", "\n", "A shop records the number of items sold in three time slots.\n", "\n", "Ask for:\n", "- morning sales;\n", "- afternoon sales;\n", "- evening sales.\n", "\n", "Convert each value to `int` and print a simple horizontal histogram.\n", "\n", "Example:\n", "\n", "```text\n", "SALES REPORT\n", "Morning | ****\n", "Afternoon | *******\n", "Evening | **\n", "\n", "Total items sold: 13\n", "```\n", "\n", "Requirements:\n", "- use `input()` and `int()`;\n", "- use `\"*\" * value`;\n", "- use `\\n` and/or `\\t`;\n", "- use at least one f-string.\n", "\n", "No loops are needed." ] }, { "cell_type": "code", "execution_count": 1, "id": "7c728c91", "metadata": { "tags": [ "solution" ] }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "\n", "SALES REPORT\n", "Morning\t\t| ***********************\n", "Afternoon\t| ************\n", "Evening\t\t| *********************\n", "\n", "Total items sold: 56\n" ] } ], "source": [ "morning = int(input(\"Morning sales: \"))\n", "afternoon = int(input(\"Afternoon sales: \"))\n", "evening = int(input(\"Evening sales: \"))\n", "\n", "total = morning + afternoon + evening\n", "\n", "print(\"\\nSALES REPORT\")\n", "print(f\"Morning\\t\\t| {'*' * morning}\")\n", "print(f\"Afternoon\\t| {'*' * afternoon}\")\n", "print(f\"Evening\\t\\t| {'*' * evening}\")\n", "print(f\"\\nTotal items sold: {total}\")" ] }, { "cell_type": "markdown", "id": "473145e8", "metadata": {}, "source": [ "## 5. Functions vs. methods — customer message formatter\n", "\n", "### Theory recall\n", "\n", "A **function** is called by name:\n", "\n", "```python\n", "len(text)\n", "```\n", "\n", "A **method** is associated with an object and is called with dot notation:\n", "\n", "```python\n", "text.upper()\n", "```\n", "\n", "Useful string methods:\n", "\n", "```python\n", "text.lower()\n", "text.upper()\n", "text.replace(old, new)\n", "```\n", "\n", "Strings are **immutable**: these methods return a new string; they do not change the original one.\n", "\n", "### Task\n", "\n", "Ask the user for a customer-service message and print:\n", "1. the original message;\n", "2. its length;\n", "3. a lowercase version;\n", "4. an uppercase version;\n", "5. a version where every occurrence of `\"urgent\"` is replaced with `\"priority\"`.\n", "\n", "Try first with:\n", "\n", "```text\n", "urgent order: urgent delivery requested\n", "```\n", "\n", "Use `len()` as a **function**, and the transformations as **methods**." ] }, { "cell_type": "code", "execution_count": null, "id": "24e6ab9a", "metadata": { "tags": [ "solution" ] }, "outputs": [], "source": [ "message = input(\"Customer message: \")\n", "\n", "lower_message = message.lower()\n", "upper_message = message.upper()\n", "revised_message = lower_message.replace(\"urgent\", \"priority\")\n", "\n", "print(f\"Original: {message}\")\n", "print(f\"Length: {len(message)}\")\n", "print(f\"Lowercase: {lower_message}\")\n", "print(f\"Uppercase: {upper_message}\")\n", "print(f\"Revised: {revised_message}\")" ] }, { "cell_type": "markdown", "id": "6000d04b", "metadata": {}, "source": [ "## 6. Conversion Detective\n", "\n", "### Theory recall\n", "\n", "`input()` always returns a **string**. \n", "If the text represents a number, it can be converted using `int()` or `float()`.\n", "\n", "```python\n", "int(\"42\") # 42\n", "float(\"3.14\") # 3.14\n", "````\n", "\n", "The content of the string must be compatible with the requested conversion.\n", "\n", "```python\n", "int(\"hello\") # ValueError\n", "int(\"3.14\") # ValueError\n", "```\n", "\n", "`int()` can also interpret a string written in a different **number base**:\n", "\n", "```python\n", "int(\"1011\", 2) # 11\n", "int(\"2F\", 16) # 47\n", "\n", "#more explicit\n", "int(\"1011\", base=2) # 11\n", "int(\"2F\", base=16) # 47\n", "```\n", "\n", "The second argument specifies how Python should interpret the digits:\n", "\n", "```python\n", "int(text, base)\n", "```\n", "\n", "For example, base `2` means binary and base `16` means hexadecimal.\n", "\n", "The digits must be valid for the selected base:\n", "\n", "```python\n", "int(\"102\", 2) # ValueError\n", "int(\"2G\", 16) # ValueError\n", "```\n", "\n", "### Task\n", "\n", "Before running the cell below, predict which expressions:\n", "\n", "* work correctly;\n", "* raise an error;\n", "* and what result you expect when they work.\n", "\n", "For each failing expression:\n", "\n", "1. identify **why** it fails;\n", "2. identify which part of the input is incompatible with the requested type or base;\n", "3. propose a corrected expression.\n", "\n", "> Run the expressions **one at a time**: execution stops at the first uncaught error.\n", "\n", "```\n", "```\n" ] }, { "cell_type": "code", "execution_count": null, "id": "02a4563b", "metadata": {}, "outputs": [], "source": [ "# Uncomment ONE expression at a time.\n", "\n", "# print(int(\"25\"))\n", "# print(int(\"3.14\"))\n", "# print(float(\"3.14\"))\n", "# print(int(\"1011\", 2))\n", "# print(int(\"102\", 2))\n", "# print(int(\"2F\", 16))\n", "# print(int(\"2G\", 16))\n", "# print(str(125))" ] }, { "cell_type": "markdown", "id": "b8474613", "metadata": {}, "source": [ "### Solution / discussion\n", "\n", "| Expression | Result |\n", "|---|---|\n", "| `int(\"25\")` | `25` |\n", "| `int(\"3.14\")` | `ValueError` |\n", "| `float(\"3.14\")` | `3.14` |\n", "| `int(\"1011\", 2)` | `11` |\n", "| `int(\"102\", 2)` | `ValueError` |\n", "| `int(\"2F\", 16)` | `47` |\n", "| `int(\"2G\", 16)` | `ValueError` |\n", "| `str(125)` | `\"125\"` |\n", "\n", "The second argument of `int()` is the **base used to interpret the string**. The result is simply a Python integer." ] } ], "metadata": { "kernelspec": { "display_name": "base", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.10.15" } }, "nbformat": 4, "nbformat_minor": 5 }